﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace IntelliTouchMix
{
    public partial class BlobController
    {
        TouchMouseEventArgs updateRealTimeEvent(int index){
            if (blobTouchMouseEventArgs[index] == null){
                MessageBox.Show("Error");
                return null;
            }
            blobTouchMouseEventArgs[index].setDistSpeedTimeVectM( calcDistSpeedTimeVect(index));
            Point2f[] v = new Point2f[6];
            TouchMouseEventArgs e = blobTouchMouseEventArgs[index];
            // Create useful vectors
            Point2f start = blobHistory[index][0].getPos();
            Point2f mid = blobHistory[index][lastFrameIndex[index] / 2].getPos();
            Point2f fin = blobHistory[index][lastFrameIndex[index]].getPos();
            v[0] = mid.sub(start);
            v[1] = fin.sub(mid);
            v[2] = fin.sub(start);
            v[3] = start.sub(mid);
            v[4] = mid.sub(fin);
            v[5] = start.sub(fin);
            v[0].normalize();
            v[1].normalize();
            v[2].normalize();
            v[3].normalize();
            v[4].normalize();
            v[5].normalize();
            float[] angs = new float[3];
            float a, b, c;
            angs[0] = v[0].getAngleFromVector(v[2]);
            angs[1] = v[1].getAngleFromVector(v[3]);
            angs[2] = v[5].getAngleFromVector(v[4]);
            e.angles = angs;
            if (v[5].x > 0)
                e.senseType = SenseType.POSITIVE;
            else if (v[5].y > 0)
                e.senseType = SenseType.POSITIVE;
            else
                e.senseType = SenseType.NEGATIVE;
            return e;
        }
        TouchMouseEventArgs detectHerradura(int index)
        {
            Point2f[] v = new Point2f[6];
            TouchMouseEventArgs e = null;
            // Create useful vectors
            Point2f start = blobHistory[index][0].getPos();
            Point2f mid = blobHistory[index][lastFrameIndex[index] / 2].getPos();
            Point2f fin = blobHistory[index][lastFrameIndex[index]].getPos();
            v[0] = mid.sub(start);
            v[1] = fin.sub(mid);
            v[2] = fin.sub(start);
            v[3] = start.sub(mid);
            v[4] = mid.sub(fin);
            v[5] = start.sub(fin);
            v[0].normalize();
            v[1].normalize();
            v[2].normalize();
            v[3].normalize();
            v[4].normalize();
            v[5].normalize();
            float[] angs = new float[3];
            float a, b, c;
            angs[0] = v[0].getAngleFromVector(v[2]);
            angs[1] = v[1].getAngleFromVector(v[3]);
            angs[2] = v[5].getAngleFromVector(v[4]);
            if (angs[1] < 140 && angs[2] > 11)
            {

                if (v[0].y > 0)
                {
                    if (v[0].x > 0)
                    {
                        if (v[1].x < 0 && v[1].y > 0)
                        {
                            e = TouchMouseEventArgs.herradura(DirectionType.RIGHT_DOWN, angs);
                            if (GestureHandler != null) GestureHandler(this, e);
                            if (CInvertedPositiveHandler != null) CInvertedPositiveHandler(this, e);
                        }
                        else
                        {
                            e = TouchMouseEventArgs.herradura(DirectionType.DOWN_RIGHT, angs);
                            if (GestureHandler != null) GestureHandler(this, e);
                            if (UPositiveHandler != null) UPositiveHandler(this, e);
                        }
                    }
                    else
                    {
                        if (v[1].x > 0 && v[1].y > 0)
                        {
                            e = TouchMouseEventArgs.herradura(DirectionType.LEFT_DOWN, angs);
                            if (GestureHandler != null) GestureHandler(this, e);
                            if (CPositiveHandler != null) CPositiveHandler(this, e);
                        }
                        else
                        {
                            e = TouchMouseEventArgs.herradura(DirectionType.DOWN_LEFT, angs);
                            if (GestureHandler != null) GestureHandler(this, e);
                            if (UNegativeHandler != null) UNegativeHandler(this, e);
                        }
                    }
                }
                else
                {

                    if (v[0].x > 0)
                    {
                        if (v[1].x < 0 && v[1].y < 0)
                        {
                            e = TouchMouseEventArgs.herradura(DirectionType.RIGHT_UP, angs);
                            if (GestureHandler != null) GestureHandler(this, e);
                            if (CInvertedNegativeHandler != null) CInvertedNegativeHandler(this, e);
                        }
                        else
                        {
                            e = TouchMouseEventArgs.herradura(DirectionType.UP_RIGHT, angs);
                            if (GestureHandler != null) GestureHandler(this, e);
                            if (UInvertedPositiveHandler != null) UInvertedPositiveHandler(this, e);
                        }
                    }
                    else
                    {
                        if (v[1].x > 0 && v[1].y < 0)
                        {
                            e = TouchMouseEventArgs.herradura(DirectionType.LEFT_UP, angs);
                            if (GestureHandler != null) GestureHandler(this, e);
                            if (CNegativeHandler != null) CNegativeHandler(this, e);
                        }
                        else
                        {
                            e = TouchMouseEventArgs.herradura(DirectionType.UP_LEFT, angs);
                            if (GestureHandler != null) GestureHandler(this, e);
                            if (UInvertedNegativeHandler != null) UInvertedNegativeHandler(this, e);
                        }
                    }
                }
            }
            return e;
        }
        TouchMouseEventArgs detectL(int i)
        {
            Point2f[] v = new Point2f[6];
            TouchMouseEventArgs e = null;
            // Create useful vectors
            Point2f start = blobHistory[i][0].getPos();
            Point2f mid = blobHistory[i][lastFrameIndex[i] / 2].getPos();
            Point2f fin = blobHistory[i][lastFrameIndex[i]].getPos();
            v[0] = mid.sub(start);
            v[1] = fin.sub(mid);
            v[2] = fin.sub(start);
            v[3] = start.sub(mid);
            v[4] = mid.sub(fin);
            v[5] = start.sub(fin);
            v[0].normalize();
            v[1].normalize();
            v[2].normalize();
            v[3].normalize();
            v[4].normalize();
            v[5].normalize();
            float[] angs = new float[3];
            float a, b, c;
            angs[0] = v[0].getAngleFromVector(v[2]);
            angs[1] = v[1].getAngleFromVector(v[3]);
            angs[2] = v[5].getAngleFromVector(v[4]);

            // Test all
           /* MessageBox.Show(""+
                            angs[0]+"\n"+
                            angs[1]+"\n"+
                            angs[2]+"\n"+
                            "fin "+v[2]+"\n"+
                            "mid0 "+v[0]+"\n"+
                            "mid1 "+v[1]+"\n"
                            );
            * */
            if (v[2].x > 0.5)
            {
                if (v[2].y > 0.5)
                {// Down Right and Right Down
                    if (v[0].y > 0.9 && v[1].x > 0.9) {
                        e = TouchMouseEventArgs.Finger(DirectionType.DOWN_RIGHT, FingerType.ONE_FINGER);
                        if (blobEventType[i] == EventType.ONE_SHOT)
                            blobGestureHandler[i] = (Gesture)LDownRight;
                      //  else if (blobEventType[i] == EventType.REAL_TIME)
                      //      blobGestureHandler[i] = (Gesture)BigVerticalDownRightRealTimeHandler;
                        //MessageBox.Show("DownRight");
                    }
                    else if (v[0].x > 0.9 && v[1].y > 0.9)
                    {
                        e = TouchMouseEventArgs.Finger(DirectionType.RIGHT_DOWN, FingerType.ONE_FINGER);
                        if (blobEventType[i] == EventType.ONE_SHOT)
                            blobGestureHandler[i] = (Gesture)LRightDown;
                        //MessageBox.Show("RightDown");
                    }
                }
                else if (v[2].y < -0.5)
                {// RightUp and UpRight
                    if (v[0].x > 0.9 && v[1].y < -0.9)
                    {
                        e = TouchMouseEventArgs.Finger(DirectionType.RIGHT_UP, FingerType.ONE_FINGER);
                        if (blobEventType[i] == EventType.ONE_SHOT)
                            blobGestureHandler[i] = (Gesture)LRightUp;
                        //MessageBox.Show("RightUp");
                    }
                    else if (v[0].y < -0.9 && v[1].x > 0.9)
                    {
                        e = TouchMouseEventArgs.Finger(DirectionType.UP_RIGHT, FingerType.ONE_FINGER);
                        if (blobEventType[i] == EventType.ONE_SHOT)
                            blobGestureHandler[i] = (Gesture)LUpRight;
                        //MessageBox.Show("UpRight");
                    }

                }
            }
            else if (v[2].x < -0.5)
            {
                if (v[2].y > 0.5)
                {// Down Left and Left Down
                    if (v[0].y > 0.9 && v[1].x < -0.9)
                    {
                        e = TouchMouseEventArgs.Finger(DirectionType.DOWN_LEFT, FingerType.ONE_FINGER);
                        if (blobEventType[i] == EventType.ONE_SHOT)
                            blobGestureHandler[i] = (Gesture)LDownLeft;
                        //MessageBox.Show("DownLeft");
                    }
                    else if (v[0].x < -0.9 && v[1].y > 0.9)
                    {
                        e = TouchMouseEventArgs.Finger(DirectionType.LEFT_DOWN, FingerType.ONE_FINGER);
                        if (blobEventType[i] == EventType.ONE_SHOT)
                            blobGestureHandler[i] = (Gesture)LLeftDown;
                        //MessageBox.Show("LeftDown");
                    }
                }
                else if (v[2].y < -0.5)
                {// LeftUp and UpRight
                    if (v[0].x < -0.9 && v[1].y < -0.9)
                    {
                        e = TouchMouseEventArgs.Finger(DirectionType.LEFT_UP, FingerType.ONE_FINGER);
                        if (blobEventType[i] == EventType.ONE_SHOT)
                            blobGestureHandler[i] = (Gesture)LLeftUp;
                        //MessageBox.Show("LeftUp");
                    }
                    else if (v[0].y < -0.9 && v[1].x < -0.9)
                    {
                        e = TouchMouseEventArgs.Finger(DirectionType.UP_LEFT, FingerType.ONE_FINGER);
                        if (blobEventType[i] == EventType.ONE_SHOT)
                            blobGestureHandler[i] = (Gesture)LUpLeft;
                        //MessageBox.Show("UpLeft");
                    }

                }
            }
            
            return e;
        }
        bool detectCircle(int index)
        {
            Point2f[] v;
            Point2f[] dv;
            int nVectores = 5;
            dv = new Point2f[nVectores - 1];
            // get first Derivative
            v = getVectorsBetweenCentroids(index, nVectores + 1);
            // get second partial derivative for x and y
            //f.setText("");
            for (int i = 0; i < nVectores - 1; i++)
            {
                dv[i] = new Point2f();
                dv[i].x = v[i + 1].x - v[i].x;
                dv[i].y = v[i + 1].y - v[i].y;
                dv[i].normalize();
                //f.addText(dv[i] + "\n");
            }
            // MessageBox.Show("Wait");
            // Verify if it always increments as a circle.
            int a, b, c;
            for (int i = 0; i < nVectores - 2; i++)
            {
                a = (int)getCurrentCase(dv[i]);
                b = (int)getCurrentCase(dv[i + 1]);
                if (a != b) return true;
                /*
                if(a==3){ // upper limit
                    c = a + b;
                    if(c==3){
                       //f.addText("Negative");
                        return true;

                    }
                    else if(c==5){
                       //f.addText("Positive");
                        return true;
                        
                    }
                    continue;
                }else{
                    c=a-b;
                    switch(c){
                        case 1:
                           //f.addText("Negative");
                            break;
                        case -1:
                           //f.addText("Positive");
                            break;
                        default:
                            continue;
                    }
                    return true;
                }*/
            }

            return false;
        }
        CircleIndex getCurrentCase(Point2f v)
        {
            if (v.x > 0)
            {
                if (v.y > 0)
                    return CircleIndex.pP;

                else
                    return CircleIndex.Pn;
            }
            else
            {
                if (v.y > 0)
                    return CircleIndex.Np;
                else
                    return CircleIndex.nN;
            }
        }
        bool detectFingerDown(int index)
        {

            Blobs currentBlob;
            int div = 3;
            int n;
            int factor;
            Blobs[] r = new Blobs[div];
            n = lastFrameIndex[index];
            factor = n / div;

            if (factor == 0) return false;
            //MessageBox.Show("Error");
            //    
            Point2f start = blobHistory[index][0].getPos();
            Point2f fin = blobHistory[index][lastFrameIndex[index]].getPos();
            Point2f vt = fin.sub(start);
            //
            for (int j = 0; j < div; j++)
            {
                r[j] = new Blobs();
                for (int i = 0; i < factor; i++)
                {
                    currentBlob = blobHistory[index][(j * factor) + i];
                    r[j].add(currentBlob);
                }
                r[j].normalize(factor);
            }
            div--;
            int[] vects = new int[div];
            // r[] should increment in number of pixels
            for (int j = 0; j < div; j++)
            {
                vects[j] = r[j + 1].getNPixels() - r[j].getNPixels();
                //   if (vects[j] < 0)
                //       return;
            }
            int vfinal = r[div].getNPixels() - r[0].getNPixels();
            if (vfinal > 3)// && vt.dist2() < 75)
            {
                vt.normalize((float)Math.Sqrt(vt.dist2()));
                //if (r[0].getNPixels() < 6 && r[div].getNPixels()>7)
                if (vt.y > hLimit)
                {
                    // MessageBox.Show("Decrease the pitch until stop" + r[0].getNPixels() + "," + r[1].getNPixels() + "," + r[2].getNPixels() + " Distancia: " + vt.dist2());
                    return true;
                }

                else
                {
                    // MessageBox.Show("Mala dir");
                }
            }
            return false;
        }
    }
}
